﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Diagnostics.Eventing.Reader;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO.Ports;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Timers;
using System.Windows.Forms;
using Microsoft.VisualBasic;


namespace ShowRadar
{
    public enum AdjustCMD
    {
        距离50mm标定 = 1,
        距离100mm标定 = 2,
        距离150mm标定 = 3,
        距离200mm标定 = 4,
        距离250mm标定 = 5,
        距离300mm标定 = 6,
        距离350mm标定 = 7,
        距离400mm标定 = 8,
        距离450mm标定 = 9,
        距离500mm标定 = 10,
        距离550mm标定 = 11,
        距离600mm标定 = 12,

    }
    public struct ColorStop
    {
        public int Position;
        public Color Color;
        public ColorStop(int position, Color color)
        {
            Position = position;
            Color = color;
        }
    }



    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            this.DoubleBuffered = true;
        }



        private bool _位置开启 = false;
        private bool linePosEnable = false;
        //串口初始化
        SerialPort Cameraport = new SerialPort();
        Stopwatch Stopwatch = new Stopwatch();

        List<LaserStruct> laserPoint = new List<LaserStruct>();
        List<LaserStruct> lineCenterPoint = new List<LaserStruct>();
        List<byte> redatal = new List<byte>();
        byte _设备地址 = 0;
        string _版本号 = "0.0.0";
        string _SN = "0000000000000000";
        byte _亮度值 = 0;
        int _曝光时长 = 0;
        byte _前置增益 = 0;
        byte _后置增益 = 0;
        byte _左侧激光亮度 = 0;
        byte _中间激光亮度 = 0;
        byte _右侧激光亮度 = 0;
        Boolean _忙线状态 = false;
        int _扫描模式 = 0; //1 雷达扫描模式，2视频扫描模式，0，停止模式

        Bitmap basiciamge;
        Bitmap videoIamge;
        GdiSystem gdi;
        //
        Graphics g1;
        Boolean apprunflag = false;

        private void Form1_Load(object sender, EventArgs e)
        {
            string[] serialnames = System.IO.Ports.SerialPort.GetPortNames();
            List<string> sortedSerialNames = serialnames.ToList();


            double width = pictureBox1.Size.Width;
            double height = pictureBox1.Size.Height;

  

            sortedSerialNames.Sort(new SerialPortComparer());
            foreach (string serialname in sortedSerialNames)
            {

                cmb_串口.Items.Add(serialname);
            }
            if (cmb_串口.Items.Count > 0)
            {
                cmb_串口.SelectedIndex = 0;
            }
            apprunflag = true;
            backgroundWorker1.RunWorkerAsync();
            timer1.Enabled = true;
            basiciamge = new Bitmap("basic.bmp");
            videoIamge = new Bitmap("videoImg.jpg");
            pictureBox1.Image = basiciamge;

            scaleH = 600 / (basiciamge.Height / 2.0); //图像刻度距离
            scaleW = 900 / (basiciamge.Width / 2.0);
            btn_开扫描.Enabled = false;
            btn_关扫描.Enabled = false;
            btn_开视频.Enabled = false;
            btn_关视频.Enabled = false;
            btn_系统复位.Enabled = false;
            btn_保存图像.Enabled = false;
            btn_发送数据.Enabled = false;
            btn_setConfig.Enabled = false;
            laserPoint.Clear();
            lineCenterPoint.Clear();
            for (int i = 0; i < 240; i++) //290个点
            {
                dgv_LinePos.Rows.Add();
                dataGridView1.Rows.Add(0, 0, 0);
                laserPoint.Add(new LaserStruct(0, 0, 0));
                lineCenterPoint.Add(new LaserStruct(0, 0, 0));
            }
        }
        //测量距离和角度
        public class SerialPortComparer : IComparer<string>
        {
            public int Compare(string x, string y)
            {
                // 提取串口号中的数字部分
                int numX = ExtractPortNumber(x);
                int numY = ExtractPortNumber(y);

                return numX.CompareTo(numY);
            }

            private int ExtractPortNumber(string portName)
            {
                // 使用正则表达式提取数字
                var match = Regex.Match(portName, @"\d+");
                return match.Success ? int.Parse(match.Value) : 0;
            }
        }

        private Point GetRadarCenter()
        {
            int centerX = basiciamge.Width / 2; // 图像宽度的一半
            int centerY = basiciamge.Height / 2; // 图像高度的一半
            return new Point(centerX, centerY);
        }


        private void btn_位置开启_Click(object sender, EventArgs e)
        {
            if (_位置开启)
            {


                btn_位置开启.Text = "位置开启"; // 设置按钮文本为开启
                _位置开启 = false; // 关闭位置显示
                               // 更新图像以清除距离和角度

            }
            else
            {
                // 如果定时器已关闭，则启动定时器

                btn_位置开启.Text = "位置关闭"; // 设置按钮文本为关闭
                _位置开启 = true; // 开启位置显示
            }
        }
        private void btn_linePosOpen_Click(object sender, EventArgs e)
        {
            linePosEnable = !linePosEnable;
            if (linePosEnable)
            {
                sendCommond(_指令.开启线激光中心坐标输出);
            }
            else
            {

                sendCommond(_指令.关闭线激光中心坐标输出);
            }
          

        }

        private void btn_linePosClose_Click(object sender, EventArgs e)
        {

        }


        private void btn_刷新_Click(object sender, EventArgs e)
        {
            string[] serialnames = System.IO.Ports.SerialPort.GetPortNames();
            foreach (string serialname in serialnames)
            {
                if (!cmb_串口.Items.Contains(serialname))
                {
                    cmb_串口.Items.Add(serialname);
                }
            }
            if (!cmb_串口.Items.Contains(cmb_串口.Text))
            {
                cmb_串口.SelectedIndex = 0;
            }
        }

        byte[] tou = { 0xA5, 0xA5, 0xA5, 0xA5 };
        public bool[] AdjustBools=new bool[] { };
        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            try
            {
                while (apprunflag)
                {
                    //Thread.Sleep(1);
                    if (Cameraport.IsOpen)
                    {
                        int len = Cameraport.BytesToRead;
                        if (len > 0)
                        {
                            byte[] data = new byte[len];
                            Cameraport.Read(data, 0, len);
                            redatal = redatal.Concat(data).ToList();
                            Stopwatch.Restart();
                        }

                        Stopwatch.Stop();
                        Stopwatch.Reset();
                        int length = redatal.Count;

                        // displog(length.ToString());

                        int startIndex = this.redatal.IndexOf(0xA5);
                        if (startIndex < 0 || length < startIndex + 8)
                        {
                            continue;
                        }
                        //判断是否为指令头
                        byte DateHeard2 = redatal[startIndex + 1];
                        byte DateHeard3 = redatal[startIndex + 2];
                        byte DateHeard4 = redatal[startIndex + 3];
                        byte DateAdress = redatal[startIndex + 4];
                        byte DateCMD = redatal[startIndex + 5];
                        byte datelenth1 = redatal[startIndex + 6];
                        byte datelenth2 = redatal[startIndex + 7];

                        int totalLenth = datelenth2 * 256 + datelenth1 + 9; //数据长度+默认数据位

                        if (DateHeard2 != 0xA5 | DateHeard3 != 0xA5 | DateHeard4 != 0xA5)
                        {
                            this.redatal.RemoveRange(0, startIndex + 1);
                            continue;
                        }
                        else
                        {
                            this.redatal.RemoveRange(0, startIndex);
                        }

                        length = redatal.Count;
                        int tempmoshi = 0;
                        byte[] cmd = null;
                        //根据指令结构生成实际指令
                        if (length >= totalLenth)
                            cmd = this.redatal.Take(totalLenth).ToArray();
                        else
                            continue;
                        this.redatal.RemoveRange(0, totalLenth);

                        //crc校验
                        byte[] addjiaoyan = cmd.Skip(4).Take(cmd.Length - 5).ToArray();
                        if (_校验码(addjiaoyan) != cmd[cmd.Length - 1])
                        {
                            displog("校验异常");
                            continue;
                        }
                        byte[] buffer = Array.Empty<byte>(); // 初始化 buffer
                        string cmdName;
                        switch ((_指令)DateCMD)
                        {
                            case _指令.设备地址:
                                //
                                _设备地址 = cmd[4];
                                // 在UI线程中更新UI
                                this.BeginInvoke((Action)(() =>
                                {
                                    relashConfig();
                                    displog("接收到设备参数值返回");
                                    // 在这里更新其他UI控件
                                }));
         
                                displog("接收到设备地址返回");
                                break;
                            case _指令.计算参数:
                                _亮度值 = cmd[8];
                                _曝光时长 = cmd[10] * 256 + cmd[9];
                                _前置增益 = cmd[11];
                                _后置增益 = cmd[12];
                                _左侧激光亮度 = cmd[13];
                                _中间激光亮度 = cmd[14];
                                _右侧激光亮度 = cmd[15];

                                // 在UI线程中更新UI
                                this.BeginInvoke((Action)(() =>
                                {
                                    relashConfig();
                                    displog("接收到设备参数值返回");
                                    // 在这里更新其他UI控件
                                }));
                         
                                displog("接收到亮度值返回");
                                break;
                            case _指令.设备重启:
                                displog("接收到设备重启");
                              
                                break;
                            case _指令.设波特率:
                              
                                displog("接受波特率成功");
                                break;
                            case _指令.版本信息:
                                string _大版本 = cmd[8].ToString();
                                string _中版本 = cmd[9].ToString();
                                string _小版本 = cmd[10].ToString();
                                _SN = Encoding.ASCII.GetString(cmd.Skip(10).Take(13).ToArray());
                                _版本号 = _大版本 + "." + _中版本 + "." + _小版本;
                                // 在UI线程中更新UI
                                this.BeginInvoke((Action)(() =>
                                {
                                    relashConfig();
                                    displog("接收到设备信息值返回");
                                    // 在这里更新其他UI控件
                                }));
                              
                                break;
                            case _指令.开始扫描:
                                tempmoshi = 1;
                                displog("接收设备扫描");
                                //分析处理解析图片
                            
                                buffer = cmd.Skip(8).Take(totalLenth-9).ToArray();
                                var localbuffer= buffer;
                                    this.Invoke((EventHandler)delegate
                                    {
                                        drawlineimagegray(localbuffer, basiciamge);
                                    });

                                

                                break;
                            case _指令.停止扫描:
                            
                                displog("接收设备停止扫描");
                                break;
                            case _指令.输出视频:
                                tempmoshi = 2;
                                displog("接收设备输出视频");
                             
                                    buffer = cmd.Skip(8).Take(38400).ToArray();
                                    this.Invoke((EventHandler)delegate
                                    {
                                        //用背景图显示点位
                                        // drawVideoImagegray(buffer, videoIamge);

                                        pictureBox1.Image = byteYUV2imagegray(buffer, 160, 240);

                                    });
                              
                                break;
                            case _指令.关闭视频:
                               
                                displog("接收设备关闭视频");
                                break;

                            case _指令.开启线激光中心坐标输出:

                                buffer = cmd.Skip(8).Take(totalLenth - 9).ToArray();
                                ParseLineDate(buffer);
                                displog("接收开启线激光中心坐标输出");
                                break;
                            case _指令.关闭线激光中心坐标输出:

                                displog("接收关闭线激光中心坐标输出");
                                break;

                            case _指令.出厂校准:
                             
                                cmdName = Enum.GetName(typeof(AdjustCMD), cmd[8]);
                                displog("接收设备【" + cmdName + "】完成");
                                break;
                            case _指令.模块标定状态读取:
                                buffer = cmd.Skip(8).Take(2).ToArray();
                                uint resUint= BytesToUInt32(buffer);
                                AdjustBools= ParseCalibrationStatus(resUint);
              
                                displog("接收设备【模块标定状态读取】完成");
                                break;

                            case _指令.模块标定初始化:
                                cmdName = Enum.GetName(typeof(AdjustCMD), cmd[8]);
                                displog("接收设备【" + cmdName + "】完成");
                                break;

                            default:
                               
                                displog("命令错误");
                                break;
                        }
                        Cameraport.DiscardInBuffer();
                    }


                }
            }
            catch (Exception)
            {


            }
          
        }

        private void ParseLineDate(byte[] buffer)
        {
            for (int j = 0; j < buffer.Length / 2; j++)
            {
                double angle = 30.0 / 159.0 * j - 15;
                double pos= (buffer[j * 2 + 1]  * 256 + buffer[j * 2]) * 0.1;
                lineCenterPoint[j].Angle = angle;
                lineCenterPoint[j].Pos = pos;
            }
  
        }

        public  uint BytesToUInt32(byte[] buffer)
        {
            if (buffer == null || buffer.Length < 2)
                throw new ArgumentException("缓冲区必须至少包含2个字节");

            // 按小端序组合字节（最低字节在索引0位置）
            return (uint)(buffer[0] |  // 最低字节 (D0-D7)
                         (buffer[1] << 8)); // 次低字节 (D8-D15)
                         //(buffer[2] << 16) |  // 次高字节 (D16-D23)
                         //(buffer[3] << 24)); // 最高字节 (D24-D31)
        }

        public  bool[] ParseCalibrationStatus(uint statusValue)
        {
            bool[] statusArray = new bool[32];

            // 遍历每一位
            for (int i = 0; i < 16; i++)
            {
                // 使用位掩码检查每一位的状态
                uint mask = (uint)(1 << i);
                statusArray[i] = (statusValue & mask) != 0;
            }

            return statusArray;
        }

        private Bitmap Bitmapclone(Bitmap sorceimage)
        {
            try
            {
                // 假设sourceBitmap是你要复制的原始Bitmap对象
                //  Bitmap sourceBitmap = new Bitmap("source_image_path");

                // 创建一个新的Bitmap对象，参数为源Bitmap的大小和像素格式
                Bitmap cloneBitmap = new Bitmap(sorceimage.Width, sorceimage.Height, sorceimage.PixelFormat);

                // 使用Clone方法复制位图
                Graphics g = Graphics.FromImage(cloneBitmap);
                g.DrawImage(sorceimage, new Rectangle(0, 0, sorceimage.Width, sorceimage.Height), new Rectangle(0, 0, sorceimage.Width, sorceimage.Height), GraphicsUnit.Pixel);
                g.Dispose();
                return cloneBitmap;
                // 现在cloneBitmap包含了sourceBitmap的副本
            }
            catch (Exception)
            {
                return null;
            }
         
        }


        private Bitmap reimage1;
        private Bitmap lastpicture;

        private double SelectAngle;

        private LaserStruct BestPoint = new LaserStruct(0, 0, 0);

        private double LimiteDis = 10;
        private object lockobj=new object();
        private void drawlineimagegray(byte[] data = null, Bitmap basicimage = null)
        {

            if (basicimage==null)
            {
                return;
            }
            //calculateDistanceAndAngle(basicimage);
            Bitmap tempImage = Bitmapclone(basicimage);
            // 复制原始图像
            Graphics g = Graphics.FromImage(tempImage);



            reimage1 = Bitmapclone(tempImage);
            pictureBox1.Image = reimage1;
            Graphics g2 = Graphics.FromImage(reimage1);
            if (data == null)
            {
                return;
            }

            double startangl1 = -45;
            double endangl1 = 0;
            double startangl2 = -45;
            double endangl2 = 0;
            double startangl3 = 0;
            double endangl3 = 45;
            double startangl4 = 0;
            double endangl4 = 45;
            double centerx = basiciamge.Width / 2.0;
            double centery = basiciamge.Height / 2.0;
            double pointNum = 80;
            try
            {
                LimiteDis = 5;
                for (int j = 0; j < data.Length / 2; j++)
                {
                    bool isSelectPoint = false;
                    //处理图像数据，先行再列,判断，保证不溢出
                    //强度问题-15°-15°
                    //整包数据长度为 322 Bytes，包含 2 Bytes 的环境数据和 160 个测距点（S1-S160），
                    //其 中每个测距点为 2 Bytes，高 4 位为强度数据，低 12 位为距离数据，单位 mm。低在前，高在后
                    //  int qiangdu = data[j*2+1]&0x7f; b >> 4
                    int qiangdu = data[j * 2 + 1] & 0xf0;

                    double juli = ((data[j * 2 + 1] & 0x0f) * 256 + data[j * 2]);
                    if (juli != 0)
                    {

                    }
                    double x = 0;
                    double y = 0;
                    double angle1;
                    double realAngle;
                    if (j < 80)
                    {
                        realAngle = (endangl1 - startangl1) / (pointNum-1) * (pointNum - 1 - j ) + (startangl1);
                        angle1 = ((endangl1 - startangl1) / (pointNum - 1) * (pointNum - 1 - j ) + (startangl1) + 90) * Math.PI / 180;
                        x = -juli * Math.Cos(angle1)/ scaleW  + centerx;
                        y = -juli * Math.Sin(angle1)/scaleH + centery;
                        laserPoint[79 - j] = new LaserStruct(realAngle, juli, qiangdu);
                    }
               
                    else
                    {
                        realAngle = (endangl4 - startangl4) / (pointNum - 1) * (2* pointNum-1 - j) + (startangl4);
                        angle1 = ((endangl4 - startangl4) / (pointNum - 1)* (2 * pointNum - 1 - j) + (startangl4) + 90) * Math.PI / 180;
                        x = -juli * Math.Cos(angle1) / scaleW + centerx;
                        y = -juli * Math.Sin(angle1) / scaleH + centery;


                        //realAngle = (endangl4 - startangl4) / 80.0 * (j - 80) + (startangl4);
                        //angle1 = ((endangl4 - startangl4) / 80.0 * (j - 80) + (startangl4) + 90) * Math.PI / 180;
                        //x = -juli * Math.Cos(angle1) / scaleW + centerx;
                        //y = -juli * Math.Sin(angle1) / scaleH + centery;
                        laserPoint[239- j] = new LaserStruct(realAngle, juli, qiangdu);
                    }
                    //判断是否为选择点
                    if (Math.Abs(realAngle - SelectAngle) < 1 && Math.Abs(realAngle - SelectAngle) < LimiteDis)
                    {
                        LimiteDis = Math.Abs(realAngle - SelectAngle);
                        BestPoint.Angle = realAngle;
                        BestPoint.Pos = juli;
                        BestPoint.Value = qiangdu;
                        isSelectPoint = true;
                    }
                  //  laserPoint[j] = new LaserStruct(realAngle, juli, qiangdu);
                    //设置颜色
                    //
                    //  reimage.SetPixel((int)x, (int)y, Color.FromArgb(255,255,255));
                    //  reimage.SetPixel((int)x, (int)y, matrixColor(qiangdu));
                    int radius = 1; // 半径，影响“点”的大小

                    for (int dx = -radius; dx <= radius; dx++)
                    {
                        for (int dy = -radius; dy <= radius; dy++)
                        {
                            if (Math.Sqrt(dx * dx + dy * dy) <= radius) // 确保在圆内
                            {
                                int drawX = (int)x + dx;
                                int drawY = (int)y + dy;

                                if (drawX >= 0 && drawX < reimage1.Width && drawY >= 0 && drawY < reimage1.Height)
                                {
                                    if (qiangdu != 0 && isSelectPoint)
                                    {
                                        BestPoint.DrawX = drawX;
                                        BestPoint.DrawY = drawY;
                                    }
                                    // reimage1.SetPixel(drawX, drawY, matrixColor(qiangdu));
                                    reimage1.SetPixel(drawX, drawY, GetColorForDistance(qiangdu));
                                }
                            }
                        }
                    }

                    //  basiciamge.SetPixel(j,);

                }
                int radius2 = 10;
                //最后画连接线
                if (BestPoint.Value != 0 && _位置开启)
                {
                    using (var brush = new SolidBrush(Color.Lime)) 
                    {
                        // 计算外接矩形（基于圆心和半径）
                        var rect = new Rectangle(
                            BestPoint.DrawX - radius2 / 4,
                             BestPoint.DrawY - radius2 / 4,
                            radius2/2,
                            radius2/2
                        );

                        // 抗锯齿配置
                        g2.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;

                        // 绘制实心圆
                        g2.FillEllipse(brush, rect);
                    }
                    Pen pen = new Pen(Color.White, 2);
                    g2.DrawLine(pen, new Point(BestPoint.DrawX, BestPoint.DrawY), new Point(reimage1.Width / 2, reimage1.Height / 2));
                }
             
            }
            catch (Exception ex)
            {
                richTextBox1.AppendText(ex.Message);
            }

            // 仅在位置开启时绘制距离和角度
            if (_位置开启 && Cursor.Position.X > 460 && Cursor.Position.Y > 105)
            {
                using (Font font = new Font("Arial", 20, FontStyle.Bold))
                {
                    Brush brush = Brushes.Red;

                    g2.DrawString($"距离: {BestPoint.Pos:F2}毫米", font, brush, new PointF(10, 10));

                    // 绘制角度
                    g2.DrawString($"角度: {BestPoint.Angle:F2}°", font, brush, new PointF(10, 40));

                    g2.DrawString($"强度: {BestPoint.Value}", font, brush, new PointF(10, 70));

                    // 绘制距离
                    //g.DrawString($"距离: {distance2:F2}毫米", font, brush, new PointF(10, 10));

                    //// 绘制角度
                    //g.DrawString($"角度: {angle2:F2}°", font, brush, new PointF(10, 40));
                }

            }
            lastpicture = reimage1;
            pictureBox1.Image = reimage1;
            g.Dispose();
            g2.Dispose();
        }

        private void drawVideoImagegray(byte[] data = null, Bitmap backImage = null)
        {
            Bitmap tempImage = Bitmapclone(backImage);
            // 复制原始图像
            Graphics g = Graphics.FromImage(tempImage);


            reimage1 = Bitmapclone(tempImage);
            pictureBox1.Image = reimage1;
            if (data == null)
            {
                return;
            }

            double centerx = backImage.Width / 2.0;
            double centery = backImage.Height / 2.0;


            lastpicture = reimage1;
            pictureBox1.Image = reimage1;

        }

        private Bitmap byteYUV2imagegray(byte[] data, int width, int height)
        {

            Bitmap reimage = new Bitmap(width, height);
            try
            {
                for (int i = 0; i < height; i++)
                {
                    for (int j = 0; j < width; j++)
                    {
                        //处理图像数据，先行在列,判断，保证不溢出
                        if (i * width + j < data.Length)
                        {
                            int gray = data[i * width + j];
                            reimage.SetPixel(j, i, Color.FromArgb(gray, gray, gray));
                            // reimage[i, j] = new Gray(data[2 * i * width + 2 * j]);
                        }
                        else
                        {
                            //保持为0
                            // reimage[i, j] = new Bgr(b, g, r);
                        }

                    }
                }
            }
            catch (Exception ex)
            {
                richTextBox1.AppendText(ex.Message);
            }
            // resize(reimage, 320, 240);
            return resize(reimage, 320, 240);
        }

        private Bitmap resize(Bitmap sourceimage, int distwidth, int distheight)
        {
            Bitmap map = new Bitmap(distwidth, distheight);
            using (Graphics gra = Graphics.FromImage(map))
            {
                gra.DrawImage(sourceimage,
                                new Rectangle(0, 0, map.Width, map.Height),
                                new Rectangle(0, 0, sourceimage.Width, sourceimage.Height),
                                GraphicsUnit.Pixel);
            }
            return map;
        }


        private Color matrixColor(int qiangdu)
        {
            //bilv最大值是128
            Color startColor = Color.Red;
            Color endColor = Color.White;
            double bilv = qiangdu / 1.0 / 128;
            int R = (int)(startColor.R * bilv + endColor.R * (1 - bilv));
            int G = (int)(startColor.G * bilv + endColor.G * (1 - bilv));
            int B = (int)(startColor.B * bilv + endColor.B * (1 - bilv));
            return Color.FromArgb(R, G, B);
        }
 

        public Color GetColorForDistance(int distance)
        {
            try
            {
            // 定义颜色关键点
            //var colorStops = new List<ColorStop>
            //                    {
            //                    new ColorStop(0, Color.Green),
            //                    new ColorStop(80,  Color.Yellow),
            //                    new ColorStop(160, Color.Orange),
            //                    new ColorStop(256,Color.Red),                        
            //                    };

                var colorStops = new List<ColorStop>
{
    new ColorStop(0,   Color.Red),
    new ColorStop(255, Color.Black)
};

                // 处理边界情况
                if (distance <= 0)
                return colorStops.First().Color;
            if (distance >= 255)
                return colorStops.Last().Color;

            // 找到相邻的两个关键点
            ColorStop lower= colorStops[0];
            ColorStop upper = colorStops[0];
            foreach (var stop in colorStops)
            {
                if (stop.Position <= distance)
                    lower = stop;
                else
                {
                    upper = stop;
                    break;
                }
            }

            // 计算插值比例
            float range = upper.Position - lower.Position;
            float ratio = (distance - lower.Position) / range;

            // 线性插值
            int r = (int)(lower.Color.R + (upper.Color.R - lower.Color.R) * ratio);
            int g = (int)(lower.Color.G + (upper.Color.G - lower.Color.G) * ratio);
            int b = (int)(lower.Color.B + (upper.Color.B - lower.Color.B) * ratio);

            return Color.FromArgb(255, r, g, b);
            }
            catch (Exception ex)
            {
                return Color.FromArgb(255, 186, 45, 0);
                throw;
            }
        }


        //private Color matrixColor(int qiangdu)
        //{
        //    //bilv最大值是128
        //    Color startColor = Color.Red;
        //    Color endColor = Color.White;
        //    double bilv = qiangdu/1.0/128;
        //    int R = (int)(startColor.R*bilv+endColor.R*(1-bilv));
        //    int G = (int)(startColor.G*bilv+endColor.G*(1-bilv));
        //    int B = (int)(startColor.B*bilv+endColor.B*(1-bilv));
        //    return Color.FromArgb(R, G, B);
        //}
        //  private 

        private void displog(string mesg)
        {
            this.Invoke((Action)(() =>
            {
                try
                {
                    richTextBox1.Clear();
                    richTextBox1.AppendText(mesg + "\r\n");
                }
                catch (Exception)
                {

                    throw;
                }

            }));
        }
        private void clearshow()
        {
            //this.Invoke((Action)(() =>
            //{
            //    richTextBox1.Clear();
            //}));
        }
        private byte _校验码(byte[] ma)
        {
            byte re = 0x00;
            foreach (byte b in ma)
            {
                re = (byte)((re + b) & 0xff);
            }

            return re;
        }

        private bool BytesCompare_Base64(byte[] b1, byte[] b2)
        {
            if (b1 == null || b2 == null) return false;
            if (b1.Length != b2.Length) return false;
            return string.Compare(Convert.ToBase64String(b1), Convert.ToBase64String(b2), false) == 0 ? true : false;
        }

        private void btn_打开串口_Click(object sender, EventArgs e)
        {
            try
            {
                if (Cameraport.IsOpen)
                {
                    Cameraport.Close();
                    btn_开扫描.Enabled = false;
                    btn_关扫描.Enabled = false;
                    btn_开视频.Enabled = false;
                    btn_关视频.Enabled = false;
                    btn_系统复位.Enabled = false;
                    btn_保存图像.Enabled = false;
                    btn_发送数据.Enabled = false;
                    btn_setConfig.Enabled = false;
                    btn_打开串口.Text = "打开串口";
                    btn_设置波特率.Enabled = false;
                    return;
                }
                if (string.IsNullOrWhiteSpace(cmb_串口.Text))
                {
                    MessageBox.Show("未找到可用串口");
                    return;
                }

                Cameraport.PortName = cmb_串口.Text;
                Cameraport.BaudRate = Convert.ToInt32(cmb_波特率.Text.Trim());
                Cameraport.DataBits = 8;
                Cameraport.StopBits = StopBits.One;
                Cameraport.Parity = Parity.None;
                Cameraport.Open();
                Cameraport.DiscardInBuffer();
                if (!(Cameraport.IsOpen))
                {
                    richTextBox1.AppendText("串口打开成功" + "\r\n");
                }
                btn_开扫描.Enabled = true;

                btn_开视频.Enabled = true;
                btn_发送数据.Enabled = true;
                btn_setConfig.Enabled = true;
                btn_系统复位.Enabled = true;
                btn_保存图像.Enabled = true;
                btn_打开串口.Text = "关闭串口";
                btn_设置波特率.Enabled = true;
            }
            catch (Exception ex)
            {


            }
         
        }
        private void relashConfig()
        {

            txt_版本号.Text = _版本号;
            txt_设备地址.Text = _设备地址.ToString();
            text_亮度值.Text = _亮度值.ToString();
            text_曝光时长.Text = _曝光时长.ToString();
            text_前置增益.Text = _前置增益.ToString();
            text_后置增益.Text = _后置增益.ToString();
            text_左侧激光亮度.Text = _左侧激光亮度.ToString();
            text_右侧激光亮度.Text = _右侧激光亮度.ToString();
            text_中间激光亮度.Text = _中间激光亮度.ToString();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            List<byte>addCMD= new List<byte>();
            addCMD.Add((byte)Convert.ToInt32(text_亮度值.Text));

            int value = Convert.ToInt32(text_曝光时长.Text);
            byte[] bytes = {
                           (byte)(value & 0xFF),   // 低字节：830 % 256 = 62 (0x3E)
                           (byte)((value >> 8) & 0xFF)  // 高字节：830 / 256 = 3 (0x03)
                           };
            addCMD.AddRange(bytes);
            addCMD.Add((byte)Convert.ToInt32(text_前置增益.Text));
            addCMD.Add((byte)Convert.ToInt32(text_后置增益.Text));
            addCMD.Add((byte)Convert.ToInt32(text_左侧激光亮度.Text));
            addCMD.Add((byte)Convert.ToInt32(text_中间激光亮度.Text));
            addCMD.Add((byte)Convert.ToInt32(text_右侧激光亮度.Text));
            sendCommond(_指令.计算参数, _设备地址, addCMD);
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            btn_开视频.Visible = isAdmin;
            btn_关视频.Visible= isAdmin;
          
          

            txt_版本号.ReadOnly = !isAdmin;
            txt_设备地址.ReadOnly =! isAdmin;
            text_中间激光亮度.ReadOnly = !isAdmin;
            text_亮度值.ReadOnly = !isAdmin;
            text_前置增益.ReadOnly = !isAdmin;
            text_右侧激光亮度.ReadOnly =!isAdmin;
            text_后置增益.ReadOnly = !isAdmin;
            text_左侧激光亮度.ReadOnly = !isAdmin;
            text_曝光时长.ReadOnly = !isAdmin;

            btn_linePosClose.Enabled = linePosEnable; // 
            btn_linePosOpen.Enabled = !linePosEnable; // 

            string selectedBaudRate = cmb_波特率.SelectedItem.ToString();
            cmb_波特率.Text = selectedBaudRate;
            if (!Cameraport.IsOpen)
            {
                btn_打开串口.BackColor = Color.Green;
            }
            else
            {
                btn_打开串口.BackColor = Color.Red;
            }
           

            //  DrawUtils.drawImage(g1, basiciamge,image_panel.Width, image_panel.Height);
            //g1.DrawImage(basiciamge, new Rectangle(0,0, image_panel.Width, image_panel.Height));
            // pictureBox1.Image=basiciamge;
            // gdi.UpdateWindow();
            if (_获取设备信息flag == 1)
            {
                sendCommond(_指令.设备地址, _设备地址);
                _获取设备信息flag++;
            }
            else if (_获取设备信息flag == 2)
            {
                sendCommond(_指令.计算参数, _设备地址);
                _获取设备信息flag++;
            }
            else if (_获取设备信息flag == 3)
            {
                sendCommond(_指令.版本信息, _设备地址);
                _获取设备信息flag = 0;
            }
            if (_if关扫描 && _if关视频)
            {
                drawlineimagegray(null, lastpicture);
            }


            //数据表显示
            if (dataGridView1.Visible)
            {
                for (int i = 0; i < laserPoint.Count; i++)
                {
                    dataGridView1.Rows[i].Cells[0].Value = laserPoint[i].Angle.ToString("0.00");
                    dataGridView1.Rows[i].Cells[1].Value = laserPoint[i].Pos.ToString("0.00");
                    dataGridView1.Rows[i].Cells[2].Value = laserPoint[i].Value.ToString("0.00");
                }
            }
            if (dgv_LinePos.Visible)
            {
                for (int i = 0; i < lineCenterPoint.Count; i++)
                {
                    dgv_LinePos.Rows[i].Cells[0].Value = lineCenterPoint[i].Angle.ToString("0.00");
                    dgv_LinePos.Rows[i].Cells[1].Value = lineCenterPoint[i].Pos.ToString("0.00");
                }
                
            }
        }


        private void btn_系统复位_Click(object sender, EventArgs e)
        {
            sendCommond(_指令.设备重启, _设备地址);
            btn_设置波特率.Enabled = true;
        }

        private void btn_设置波特率_Click(object sender, EventArgs e)
        {
            List<byte> addCmd=new List<byte>();
            addCmd.Add((byte)cmb_波特率.SelectedIndex);
            sendCommond(_指令.设波特率, _设备地址, addCmd);
            //Cameraport.BaudRate = Convert.ToInt32(cmb_波特率.Text.Trim());
            btn_设置波特率.Enabled = false;
        }
        private void sendCommond(_指令 zhiing, byte 设备地址, List<byte> botelv= null )
        {
            List<byte> senddata = new List<byte>();

            byte IsSet = 0x00;
            if (botelv!=null)
            {
                IsSet= (byte)botelv.Count;
            }
            senddata.Add(0x00);
            senddata.Add((byte)zhiing);
            senddata.Add(IsSet);
            senddata.Add(0x00);
            if (botelv != null)
            {
                
                senddata.AddRange(botelv);
            }

            senddata.Add(_校验码(senddata.ToArray()));
            byte[] finalsend = tou.Concat(senddata).ToArray();
            if (Cameraport.IsOpen)
            {
                Cameraport.Write(finalsend, 0, finalsend.Length);
            }

        }
        public void sendCommond(_指令 zhiing,  List<byte> botelv = null)
        {
            List<byte> senddata = new List<byte>();

            byte IsSet = 0x00;
            if (botelv != null)
            {
                IsSet = (byte)botelv.Count;
            }
            senddata.Add(0x00);
            senddata.Add((byte)zhiing);
            senddata.Add(IsSet);
            senddata.Add(0x00);
            if (botelv != null)
            {

                senddata.AddRange(botelv);
            }

            senddata.Add(_校验码(senddata.ToArray()));
            byte[] finalsend = tou.Concat(senddata).ToArray();
            if (Cameraport.IsOpen)
            {
                Cameraport.Write(finalsend, 0, finalsend.Length);
            }

        }

        int _获取设备信息flag = 0;
        private void btn_获取设备信息_Click(object sender, EventArgs e)
        {
            _版本号 = "0.0.0";
            //放到tick中发送。
            _获取设备信息flag = 1;

        }

        private void btn_开扫描_Click(object sender, EventArgs e)
        {
            _if关扫描 = false;
            try
            {
                sendCommond(_指令.开始扫描, _设备地址);
            }
            catch (Exception)
            {

            }
         
            btn_关扫描.Enabled = true;
            btn_开扫描.Enabled = false;
        }
        private bool _if关扫描 = false;
        private void btn_关扫描_Click(object sender, EventArgs e)
        {
            _if关扫描 = true;
            try
            {
                sendCommond(_指令.停止扫描, _设备地址);
            }
            catch (Exception)
            {
              
            }
  
            btn_开扫描.Enabled = true;
            btn_关扫描.Enabled = false;
        }

        private void btn_开视频_Click(object sender, EventArgs e)
        {
            _if关视频 = false;
            sendCommond(_指令.输出视频, _设备地址);
            btn_关视频.Enabled = true;
            btn_开视频.Enabled = false;
        }
        private bool _if关视频 = true;
        private void btn_关视频_Click(object sender, EventArgs e)
        {
            _if关视频 = true;
            sendCommond(_指令.关闭视频, _设备地址);
            btn_开视频.Enabled = true;
            btn_关视频.Enabled = false;
        }

      
        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (Cameraport.IsOpen)
            {
                Cameraport.Close();
            }
            apprunflag = false;
            Environment.Exit(0);
        }

        private void btn_保存图像_Click(object sender, EventArgs e)
        {

            SaveFileDialog saveFileDialog1 = new SaveFileDialog();
            try
            {
                // tempdev.modelone.mainvppblock = cogToolBlockEditV21.Subject;

                saveFileDialog1.Filter = "ALL Image Files|*.jpg";
                // saveFileDialog1.InitialDirectory = 外设.SysPras.Vpppath;
                if (saveFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                {
                    string path = saveFileDialog1.FileName;
                    //写数据
                    //tempdev.Savemode(path, tempdev.modelone);
                    pictureBox1.Image.Save(path);
                }
            }
            catch (Exception ex)
            {
                richTextBox1.AppendText(ex.Message);
            }
        }

        private void pictureBox1_Click(object sender, EventArgs e)
        {

        }

        private void txt_设备地址_TextChanged(object sender, EventArgs e)
        {

        }

        private void btn_发送数据_Click(object sender, EventArgs e)
        {
            sendCommond(_指令.计算参数, _设备地址);
            //Cameraport.Close(); // 关闭串口
        }

        private void cmb_波特率_SelectedIndexChanged(object sender, EventArgs e)
        {

        }

        double test_dis2;
        double test_angle2;
        double scaleH;
        double scaleW;
        private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
        {
            double x = e.Location.X;
            double y = e.Location.Y;

            if (_位置开启)
            {
                double width = pictureBox1.Size.Width;
                double height = pictureBox1.Size.Height;


                test_dis2 = Math.Sqrt(Math.Pow((x - width / 2) * scaleW, 2) +
                  Math.Pow((y - height / 2) * scaleH, 2));

                Point mousePosition = this.PointToClient(Cursor.Position);
                // 计算距离和角度
                //double distance2 = Math.Sqrt(Math.Pow(mousePosition.X - 1212, 2) +
                //                 Math.Pow(mousePosition.Y - 554, 2)) / 457 * 400;

                double deltaX = x - width / 2;
                double deltaY = height / 2 - y; // 反转Y轴因为Y坐标向下增加
                test_angle2 = Math.Atan2(deltaX, deltaY) * (180.0 / Math.PI); // 转换为度
                SelectAngle = test_angle2;
            }
        }

      

        private void dataGridView1_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
        {
            // 在CellPainting事件中，绘制序号
            if (e.RowIndex >= 0 && e.ColumnIndex == -1)
            {
                e.Paint(e.CellBounds, DataGridViewPaintParts.All & ~DataGridViewPaintParts.ContentForeground);

                // 计算序号的位置，使其在单元格中居中
                string text = (e.RowIndex + 1).ToString();
                SizeF textSize = e.Graphics.MeasureString(text, e.CellStyle.Font);
                PointF position = new PointF(
                    e.CellBounds.Left + (e.CellBounds.Width - textSize.Width) / 2,
                    e.CellBounds.Top + (e.CellBounds.Height - textSize.Height) / 2);

                using (Brush brush = new SolidBrush(e.CellStyle.ForeColor))
                {
                    e.Graphics.DrawString(text, e.CellStyle.Font, brush, position);
                }

                e.Handled = true;
            }
        }
        bool isAdmin = false;
        Frm_Adjust childForm = null;
        private void label3_DoubleClick(object sender, EventArgs e)
        {
            if (isAdmin)
            {
                isAdmin = false;
                return;
            }
               
            

            // 弹出密码输入框
            string password = Interaction.InputBox(
                "请输入密码",    // 提示信息
                "密码验证",      // 标题
                "",              // 默认值
                Screen.PrimaryScreen.Bounds.Width / 4,  // 弹窗位置X坐标
                Screen.PrimaryScreen.Bounds.Height / 4  // 弹窗位置Y坐标
            );

            if (password != "123456789")
            {
                MessageBox.Show("密码错误！");
            }
            else
            {
                if (childForm==null)
                {
                    childForm = new Frm_Adjust();
                }
               
                childForm.Owner = this; // 这里的this是主窗体的实例
                childForm.Show();
                isAdmin =true;
            }
        }

        private void label3_Click(object sender, EventArgs e)
        {

        }

        private void dataGridView2_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
        {
            // 在CellPainting事件中，绘制序号
            if (e.RowIndex >= 0 && e.ColumnIndex == -1)
            {
                e.Paint(e.CellBounds, DataGridViewPaintParts.All & ~DataGridViewPaintParts.ContentForeground);

                // 计算序号的位置，使其在单元格中居中
                string text = (e.RowIndex + 1).ToString();
                SizeF textSize = e.Graphics.MeasureString(text, e.CellStyle.Font);
                PointF position = new PointF(
                    e.CellBounds.Left + (e.CellBounds.Width - textSize.Width) / 2,
                    e.CellBounds.Top + (e.CellBounds.Height - textSize.Height) / 2);

                using (Brush brush = new SolidBrush(e.CellStyle.ForeColor))
                {
                    e.Graphics.DrawString(text, e.CellStyle.Font, brush, position);
                }

                e.Handled = true;
            }
        }

 
    }

    /*
     * 0x60	获取设备地址 
0x61	 获取计算参数 （数据校准）
0x62	获取版本信息 
0x63	开始扫描，输出点云数据 
0x64	停机，停止扫描 
0x67	 设备软重启
0x68	设置串口波特率 
0x83	开始扫描，输出视频数据 
0x84	停止视频输出
0xF1	模式出厂校准-中间角度
0xF2	模式出厂校准-两侧角度

     */
    public enum _指令 : byte
    {
        设备地址 = 0x60,
        计算参数 = 0x61,
        版本信息 = 0x62,
        开始扫描 = 0x63,
        停止扫描 = 0x64,
        设备重启 = 0x67,
        设波特率 = 0x68,
        输出视频 = 0x83,
        关闭视频 = 0x84,
        开启线激光中心坐标输出= 0x85,
        关闭线激光中心坐标输出= 0x86,
        出厂校准 = 0xF1,
        模块标定状态读取= 0xF2,
        模块标定初始化 = 0xF3
    }


    public class GdiSystem : IDisposable
    {
        Panel thisWindow;

        /// <summary>
        /// Convert a form to LayeredWindow
        /// call this in Load event
        /// </summary>
        /// <param name="attachForm"></param>
        ///  <param name="operateable">indicates whether the window will process input events.</param>
        public GdiSystem(Panel attachForm, bool operateable = false)
        {
            thisWindow = attachForm;
            if (attachForm.Handle != IntPtr.Zero)
            {
                Win32.SetWindowLong(attachForm.Handle, Win32.GWL_EXSTYLE, Win32.GetWindowLong(attachForm.Handle, Win32.GWL_EXSTYLE) | Win32.WS_EX_LAYERED);
                if (!operateable)
                {
                    Win32.SetWindowLong(attachForm.Handle, Win32.GWL_EXSTYLE, Win32.GetWindowLong(attachForm.Handle, Win32.GWL_EXSTYLE) | Win32.WS_EX_TRANSPARENT);
                }
            }
            else
            {
                throw new AccessViolationException("Window not initialized.");
            }
            oldBits = IntPtr.Zero;
            screenDC = Win32.GetDC(IntPtr.Zero);
            hBitmap = IntPtr.Zero;
            memDc = Win32.CreateCompatibleDC(screenDC);
            blendFunc.BlendOp = Win32.AC_SRC_OVER;
            blendFunc.SourceConstantAlpha = 255;
            blendFunc.AlphaFormat = Win32.AC_SRC_ALPHA;
            blendFunc.BlendFlags = 0;

            initBitmaps();

        }

        private void initBitmaps()
        {
            thisBitmap = new Bitmap(thisWindow.Width, thisWindow.Height);
            thisGraphics = Graphics.FromImage(thisBitmap);
            bitMapSize = new Win32.Size(thisBitmap.Width, thisBitmap.Height);

        }
        /// <summary>
        /// Get a Graphic object.
        /// </summary>
        public Graphics Graphics
        {
            get
            {
                return thisGraphics;
            }
        }
        /// <summary>
        /// Apply content after paint on the Graphic
        /// </summary>
        public void UpdateWindow()
        {
            SetBits(thisBitmap);
        }
        IntPtr oldBits;
        IntPtr screenDC;
        IntPtr hBitmap;
        IntPtr memDc;
        Win32.BLENDFUNCTION blendFunc = new Win32.BLENDFUNCTION();

        Win32.Point topLoc = new Win32.Point(0, 0);
        Win32.Size bitMapSize;
        Win32.Point srcLoc = new Win32.Point(0, 0);


        IntPtr graphicDC;
        private void SetBits(Bitmap bitmap)
        {
            if (!Bitmap.IsCanonicalPixelFormat(bitmap.PixelFormat) || !Bitmap.IsAlphaPixelFormat(bitmap.PixelFormat))
                throw new ApplicationException("The picture must be 32bit picture with alpha channel.");
            try
            {
                topLoc.x = thisWindow.Left;
                topLoc.y = thisWindow.Top;
                hBitmap = thisBitmap.GetHbitmap(Color.FromArgb(0));
                oldBits = Win32.SelectObject(memDc, hBitmap);
                Win32.BitBlt(memDc, 0, 0, bitMapSize.cx, bitMapSize.cy, graphicDC, 0, 0, 0x00CC0020);
                Win32.UpdateLayeredWindow(thisWindow.Handle, screenDC, ref topLoc, ref bitMapSize, memDc, ref srcLoc, 0, ref blendFunc, Win32.ULW_ALPHA);
            }
            finally
            {
                if (hBitmap != IntPtr.Zero)
                {
                    Win32.SelectObject(memDc, oldBits);
                    Win32.DeleteObject(hBitmap);
                }
            }
        }

        public void Dispose()
        {
            Win32.ReleaseDC(IntPtr.Zero, screenDC);
            Win32.DeleteDC(memDc);

        }

        private Bitmap thisBitmap;
        private Graphics thisGraphics;


        class Win32
        {
            [StructLayout(LayoutKind.Sequential)]
            public struct Size
            {
                public Int32 cx;
                public Int32 cy;

                public Size(Int32 x, Int32 y)
                {
                    cx = x;
                    cy = y;
                }
            }

            [System.Runtime.InteropServices.DllImport("gdi32.dll")]
            public static extern int BitBlt(
                IntPtr hdcDest,     // handle to destination DC (device context)
                int nXDest,         // x-coord of destination upper-left corner
                int nYDest,         // y-coord of destination upper-left corner
                int nWidth,         // width of destination rectangle
                int nHeight,        // height of destination rectangle
                IntPtr hdcSrc,      // handle to source DC
                int nXSrc,          // x-coordinate of source upper-left corner
                int nYSrc,          // y-coordinate of source upper-left corner
                System.Int32 dwRop  // raster operation code
            );

            [StructLayout(LayoutKind.Sequential, Pack = 1)]
            public struct BLENDFUNCTION
            {
                public byte BlendOp;
                public byte BlendFlags;
                public byte SourceConstantAlpha;
                public byte AlphaFormat;
            }

            [StructLayout(LayoutKind.Sequential)]
            public struct Point
            {
                public Int32 x;
                public Int32 y;

                public Point(Int32 x, Int32 y)
                {
                    this.x = x;
                    this.y = y;
                }
            }

            public const byte AC_SRC_OVER = 0;
            public const Int32 ULW_ALPHA = 2;
            public const byte AC_SRC_ALPHA = 1;
            public const int GWL_EXSTYLE = -20;
            public const int WS_EX_TRANSPARENT = 0x20;
            public const int WS_EX_LAYERED = 0x80000;

            [DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)]
            public static extern IntPtr CreateCompatibleDC(IntPtr hDC);

            [DllImport("user32.dll", ExactSpelling = true, SetLastError = true)]
            public static extern IntPtr GetDC(IntPtr hWnd);

            [DllImport("gdi32.dll", ExactSpelling = true)]
            public static extern IntPtr SelectObject(IntPtr hDC, IntPtr hObj);

            [DllImport("user32.dll", ExactSpelling = true)]
            public static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC);

            [DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)]
            public static extern int DeleteDC(IntPtr hDC);

            [DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)]
            public static extern int DeleteObject(IntPtr hObj);

            [DllImport("user32.dll", ExactSpelling = true, SetLastError = true)]
            public static extern int UpdateLayeredWindow(IntPtr hwnd, IntPtr hdcDst, ref Point pptDst, ref Size psize, IntPtr hdcSrc, ref Point pptSrc, Int32 crKey, ref BLENDFUNCTION pblend, Int32 dwFlags);

            [DllImport("gdi32.dll", ExactSpelling = true, SetLastError = true)]
            public static extern IntPtr ExtCreateRegion(IntPtr lpXform, uint nCount, IntPtr rgnData);

            [DllImport("user32.dll", EntryPoint = "GetWindowLongA")]
            public static extern int GetWindowLong(IntPtr hwnd, int nIndex);

            [DllImport("user32.dll", EntryPoint = "SetWindowLongA")]
            public static extern int SetWindowLong(IntPtr hwnd, int nIndex, int dwNewLong);

        }
    }

    public class DrawUtils
    {
        #region drawAlphaImage
        /// <summary>
        /// Draw a image on the specified graphic with specified alpha
        /// </summary>
        /// <param name="g"></param>
        /// <param name="image"></param>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="w"></param>
        /// <param name="h"></param>
        /// <param name="alpha"></param>
        public static void drawAlphaImage(Graphics g, Image image, float x, float y, float w, float h, float alpha)
        {
            if (alpha >= 0.99)
            {
                g.DrawImage(image, x, y, w, h);
                return;
            }
            g.DrawImage(image, new Rectangle((int)x, (int)y, (int)w, (int)h), 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, alphaImage(alpha));
        }

        public static void drawImage(Graphics g, Image image, int w, int h)
        {

            g.DrawImage(image, new Rectangle(0, 0, w, h));
        }
        private static ImageAttributes alphaAttrs = new ImageAttributes();
        private static ColorMatrix cmx = new ColorMatrix(new float[][]{
                new float[5]{ 1,0,0,0,0 },
                new float[5]{ 0,1,0,0,0 },
                new float[5]{ 0,0,1,0,0 },
                new float[5]{ 0,0,0,0.5f,0 },
                new float[5]{ 0,0,0,0,0 }
            });
        private static ImageAttributes alphaImage(float alpha)
        {
            cmx.Matrix33 = alpha;
            alphaAttrs.SetColorMatrix(cmx, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);
            return alphaAttrs;
        }
        #endregion

        #region drawRotateImg
        /// <summary>
        /// Draw image rotated from the center
        /// </summary>
        /// <param name="g"></param>
        /// <param name="img"></param>
        /// <param name="angle"></param>
        /// <param name="centerX"></param>
        /// <param name="centerY"></param>
        public static void drawRotateImg(Graphics g, Image img, float angle, float centerX, float centerY)
        {
            drawRotateImg(g, img, angle, centerX, centerY, img.Width, img.Height);
        }
        /// <summary>
        /// Draw image rotated from the center, with specified size
        /// </summary>
        /// <param name="g"></param>
        /// <param name="img"></param>
        /// <param name="angle"></param>
        /// <param name="centerX"></param>
        /// <param name="centerY"></param>
        /// <param name="imgW"></param>
        /// <param name="imgH"></param>
        public static void drawRotateImg(Graphics g, Image img, float angle, float centerX, float centerY, float imgW, float imgH)
        {
            float width = imgW;
            float height = imgH;
            Matrix mtrx = new Matrix();
            mtrx.RotateAt(angle, new PointF((width / 2), (height / 2)), MatrixOrder.Append);
            //得到旋转后的矩形
            GraphicsPath path = new GraphicsPath();
            path.AddRectangle(new RectangleF(0f, 0f, width, height));
            RectangleF rct = path.GetBounds(mtrx);
            Point Offset = new Point((int)(rct.Width - width) / 2, (int)(rct.Height - height) / 2);
            //构造图像显示区域：让图像的中心与窗口的中心点一致
            RectangleF rect = new RectangleF(-width / 2 + centerX, -height / 2 + centerY, (int)width, (int)height);
            PointF center = new PointF((int)(rect.X + rect.Width / 2), (int)(rect.Y + rect.Height / 2));
            g.TranslateTransform(center.X, center.Y);
            g.RotateTransform(angle);
            //恢复图像在水平和垂直方向的平移
            g.TranslateTransform(-center.X, -center.Y);
            g.DrawImage(img, rect);
            //重至绘图的所有变换
            g.ResetTransform();
        }

        #endregion
    }
}
